package com.lanyou.esb.cook.proxy.service.impl;

import java.io.IOException;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.fasterxml.jackson.databind.JsonMappingException;
import com.lanyou.esb.cook.proxy.common.Constants;
import com.lanyou.esb.cook.proxy.common.SystemResCode;
import com.lanyou.esb.cook.proxy.dao.impl.BaseDao;
import com.lanyou.esb.cook.proxy.entity.Token;
import com.lanyou.esb.cook.proxy.exception.AuthException;
import com.lanyou.esb.cook.proxy.redis.proxy.impl.TokenJedisProxy;
import com.lanyou.esb.cook.proxy.service.TokenService;
//git.oschina.net/gongleister/cookproxy.git
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
//git.oschina.net/gongleister/cookproxy.git
import com.lanyou.esb.cook.proxy.exception.PersistentDataException;

/**
 * 令牌服务 
 * 
 * @author Davey.wu
 */
public class TokenServiceImpl implements TokenService {
	/** 数据库操作接口 **/
	private BaseDao<Token> dao;
	/** Redis代理接口 **/
	private TokenJedisProxy jedisProxy;

	@Override
	public Token getToken(String systemCode, String ifCode, String ifVersion,
			String callSystemCode) throws Exception {
		try {
			// 获取令牌
			return jedisProxy.hget(jedisProxy.getKeyFromFields(systemCode,
					ifCode, ifVersion, callSystemCode));
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			throw e;
		}
		return null;
	}

	@Override
	public Token getToken4Acc(String applyKey, String systemCode,
			String ifCode, String ifVersion) throws Exception {
		try {
			// 获取令牌
			return jedisProxy.hget(jedisProxy.getKeyFromFields(applyKey,
					systemCode, ifCode, ifVersion));
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			throw e;
		}
		return null;
	}

	@Override
	public Token getToken(String applyKey, String ifCode, String ifVersion)
			throws Exception {
		try {
			// 获取令牌
			return jedisProxy.hget(jedisProxy.getKeyFromFields(applyKey,
					ifCode, ifVersion));
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			throw e;
		}
		return null;
	}

	@Override
	public Token getTestToken(String systemCode, String ifCode,
			String ifVersion, String callSystemCode) {
		try {
			// 获取测试令牌
			return ((TokenJedisProxy) jedisProxy).getHash4TestToken(jedisProxy
					.getKeyFromFields(systemCode, ifCode, ifVersion,
							callSystemCode));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void loadAllToRedis() {
		try {
			jedisProxy.loadHashAll(dao.findAll());
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public Token updateToken(final Token token) throws AuthException {
		try {
			TransactionTemplate tt = new TransactionTemplate(
					this.dao.getTransactionManager());
			tt.execute(new TransactionCallback() {
				public Object doInTransaction(TransactionStatus status) {
					// 保存令牌到数据库
					dao.update(token);
					try {
						// 保存令牌REDIS
						jedisProxy.hset(jedisProxy.getKeyFromObject(token),
								token);
					} catch (Exception e) {
						throw new PersistentDataException(e.getMessage());
					}
					return null;
				}
			});
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return token;
	}

	@Override
	public Token updateTestToken(Token token) throws AuthException {
		try {
			// 保存测试令牌
			((TokenJedisProxy) jedisProxy).saveHash4TestToken(
					jedisProxy.getKeyFromObject(token), token);
		} catch (Exception e) {
			// 更新访问令牌失败，抛出异常
			throw new AuthException(SystemResCode.MSG_ACCESSTOKEN_UPDATE_ERROR
					+ Constants.FLAG_DOT_SYMBOL + Constants.MSG_DETIAL
					+ e.getMessage(),
					SystemResCode.CODE_ACCESSTOKEN_UPDATE_ERROR);
		}
		return token;
	}

	@Override
	public void reload(Token token) {
		try {
			jedisProxy.reloadHash(token);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public TokenJedisProxy getJedisProxy() {
		return jedisProxy;
	}

	public void setJedisProxy(TokenJedisProxy jedisProxy) {
		this.jedisProxy = jedisProxy;
	}

	public BaseDao<Token> getDao() {
		return dao;
	}

	public void setDao(BaseDao<Token> dao) {
		this.dao = dao;
	}
}
